package com.csc.dao;

import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.csc.constants.Constants;
import com.csc.domain.Account;
import com.csc.domain.Transaction;

@Repository
public class TransactionDaoImpl implements TransactionDao {

	@PersistenceContext
	private EntityManager em;

	final static Logger logger = Logger.getLogger(TransactionDaoImpl.class);

	// HoangHung
	public List<Transaction> getTransactionListByAccountId(int accountId) {

		logger.info("get Transaction List By User Id Start");

		TypedQuery<Transaction> query = em
				.createQuery(
						"SELECT t FROM Transaction t WHERE t.sendAccountId.accountId= :accountId",
						Transaction.class);

		return query.setParameter("accountId", accountId).getResultList();
	}

	// HoangHung
	public List<Transaction> getTransactionListByCustomer(Date from, Date to,
			int userId) {
		logger.info("get Transaction List By Customer Start");

		TypedQuery<Transaction> query = em
				.createQuery(
						"SELECT t FROM Transaction t WHERE t.beginTime >= :from and t.endTime <= :to and t.sendAccountId.accountId= :userId",
						Transaction.class);

		return query.setParameter("from", from).setParameter("to", to)
				.setParameter("userId", userId).getResultList();
	}

	// TrangNguyen
	public List<Transaction> getTransactionListPending() {

		logger.info("Start Get Transaction List Pending ");

		TypedQuery<Transaction> query = em
				.createQuery(
						"SELECT t FROM  Transaction t WHERE t.transactionStatus = :statusPending ORDER BY t.idTransaction ",
						Transaction.class).setParameter("statusPending",
						"Pending");
		return query.getResultList();
	}


	// TrangNguyen
	public Transaction findTransactionById(int transactionId) {
		logger.info("Start Find Transaction By Id = " + transactionId);
		return em.find(Transaction.class, transactionId);
	}

	// TrangNguyen
	@Transactional
	public boolean insertNewTransaction(Transaction newTransaction) {
		logger.info("Insert New Transaction");
		em.persist(newTransaction);
		return true;
	}

	// TrangNguyen
	public Transaction findTransactionByStringId(String transactionId) {
		logger.info("Start Find Transaction By Id = " + transactionId);

		try {
			Integer.parseInt(transactionId);
		} catch (NumberFormatException e) {
			logger.info("Transaction Id = " + transactionId + " not valid");
			return null;
		}
		return em.find(Transaction.class, Integer.parseInt(transactionId));

	}

	// TrangNguyen
	@Transactional
	public boolean updateTransaction(Transaction transaction) {

		logger.info("Update trasaction id = " + transaction.getIdTransaction());
		em.merge(transaction);
		return true;
	}

	// TrangNguyen
	@Transactional
	public boolean update(Account account, Transaction transaction) {
		logger.info("Update account, transaction");
		em.merge(transaction);
		em.merge(account);
		return true;
	}
	
	// TrangNguyen
	@Transactional
	public boolean update(Account sendAccount,Account receiveAccount, Transaction transaction){
		logger.info("Update sendaccount, receiveAccount, transaction");
		em.merge(transaction);
		em.merge(sendAccount);
		em.merge(receiveAccount);
		return true;
	}

	public List<Transaction> getTransactionListComplete() {
		logger.info("Start Get Transaction List Complete ");

		TypedQuery<Transaction> query = em
				.createQuery(
						"SELECT t FROM  Transaction t WHERE t.transactionStatus = :statusApproved OR t.transactionStatus = :statusRejected ORDER BY t.endTime DESC",
						Transaction.class).setParameter("statusApproved",
						Constants.TRANSACTION_STATE_APPROVED).setParameter("statusRejected",
								Constants.TRANSACTION_STATE_REJECTED);
		return query.getResultList();
	}

}
